package com.reone.xiaozu.app.view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View
import com.reone.xiaozu.R

/**
 * Created by wangxingsheng on 2017/7/28.
 *
 * 动态箭头
 *
 */

class DynamicArrowView : View {

    companion object {

        /**
         * 补帧参数，数字越大补帧越多，变化会感觉更慢
         */
        private const val mPatch = 5
//        private const val TAG = "DynamicArrowView "

        /**
         * 箭头边缘预留位置
         */
        private const val mDefaultPadding = 5

    }

    /**
     * fps，数字越大变化越快
     */
    private var fps = 30

    /**
     * 箭头方向，是否向右
     */
    private var mDirection = Direction.LEFT


    private var mFigure = Figure.ARROWS

    /**
     * 移动速度
     */
    private var mSpeed: Int = 0
    private val mAlphaArea = intArrayOf(33, 99)

    private var mHeight: Int = 0
    private var mWidth: Int = 0
    /**
     * 箭头的线条宽度
     */
    private var mPaintWidth = 10f
    /**
     * 两个箭头之间的间隔
     */
    private var mPadding = 15

    /**
     * 箭头的个数
     */
    private var mArrowCount = 3

    /**
     * 画笔的集合，有多少个箭头就有多少个画笔
     */
    private lateinit var mPaints: Array<Paint>
    private lateinit var mBaseAlphas: IntArray

    /**
     * 基础颜色
     */
    private var mBaseColor: Int = 0

    /**
     * 画图的形状
     */
    private enum class Figure {
        RECTANGLE   //长方形
        ,
        ROUND      //圆形
        ,
        ARROWS   //箭头 三角形
    }

    /**
     * 变化方向
     */
    private enum class Direction {
        LEFT        //向左
        ,
        RIGHT      //向右
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init(context, attrs, 0)
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init(context, attrs, defStyleAttr)
    }

    @SuppressLint("NewApi")
    private fun init(context: Context, attrs: AttributeSet?, defStyleAttr: Int) {
        val a = context.theme.obtainStyledAttributes(attrs, R.styleable.DynamicArrowView, defStyleAttr, 0)
        mBaseColor = getContext().resources.getColor(R.color.colorAccent)
        if (a != null) {
            mDirection = Direction.values()[a.getInteger(R.styleable.DynamicArrowView_direction, Direction.LEFT.ordinal)]
            mBaseColor = getContext().resources.getColor(a.getResourceId(R.styleable.DynamicArrowView_baseColor, R.color.colorAccent))
            mPadding = a.getInteger(R.styleable.DynamicArrowView_basePadding, 15)
            fps *= a.getInt(R.styleable.DynamicArrowView_fpsMultiple, 1)
            mPaintWidth = a.getInteger(R.styleable.DynamicArrowView_paintWidth, 10).toFloat()
            mArrowCount = a.getInteger(R.styleable.DynamicArrowView_arrowsCount, 3)
            mFigure = Figure.values()[a.getInteger(R.styleable.DynamicArrowView_figure, Figure.ARROWS.ordinal)]
        }
        mPaints = Array(mArrowCount){
            return@Array Paint()
        }
        mBaseAlphas = IntArray(mArrowCount)
        mSpeed = (mAlphaArea[1] - mAlphaArea[0]) / mArrowCount
        for (i in 0 until mArrowCount) {
            mPaints[i] = Paint()
            mPaints[i].color = mBaseColor
            when (mFigure) {
                Figure.RECTANGLE, Figure.ROUND -> mPaints[i].style = Paint.Style.FILL
                Figure.ARROWS -> mPaints[i].style = Paint.Style.STROKE
            }
            mPaints[i].strokeWidth = mPaintWidth
            mPaints[i].strokeJoin = Paint.Join.ROUND
            mPaints[i].strokeCap = Paint.Cap.ROUND
            mPaints[i].isAntiAlias = true
            mBaseAlphas[i] = if (mDirection == Direction.RIGHT) mAlphaArea[1] - i * mSpeed else mAlphaArea[0] + i * mSpeed
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        mHeight = h
        mWidth = w
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        for (index in 0 until mArrowCount) {
            changePaintColor(index)
            drawFigure(canvas, index)
        }
        postInvalidateDelayed((1000 / fps).toLong())
    }

    /**
     * 画箭头
     * @param canvas
     * @param index
     */
    private fun drawArrows(canvas: Canvas, index: Int) {
        val itemWidth = mWidth / mArrowCount
        val path = Path()
        if (mDirection == Direction.LEFT) {
            path.moveTo(((index + 1) * itemWidth).toFloat() - mPadding.toFloat() - mPaintWidth / 2, 0f + mPaintWidth / 2 + mDefaultPadding.toFloat())// 箭头定点
            path.lineTo((index * itemWidth).toFloat() + mPaintWidth / 2 + mDefaultPadding.toFloat(), (mHeight / 2).toFloat())
            path.lineTo(((index + 1) * itemWidth).toFloat() - mPadding.toFloat() - mPaintWidth / 2, mHeight.toFloat() - mPaintWidth / 2 - mDefaultPadding.toFloat())
        } else {
            path.moveTo((index * itemWidth).toFloat() + mPadding.toFloat() + mPaintWidth / 2, 0f + mPaintWidth / 2 + mDefaultPadding.toFloat())// 箭头定点
            path.lineTo(((index + 1) * itemWidth).toFloat() - mPaintWidth / 2 - mDefaultPadding.toFloat(), (mHeight / 2).toFloat())
            path.lineTo((index * itemWidth).toFloat() + mPadding.toFloat() + mPaintWidth / 2, mHeight.toFloat() - mPaintWidth / 2 - mDefaultPadding.toFloat())
        }
        canvas.drawPath(path, mPaints[index])
    }

    /**
     * 画长方形
     * @param canvas
     * @param index
     */
    private fun drawRectangle(canvas: Canvas, index: Int) {
        val itemWidth = mWidth / mArrowCount
        canvas.drawRect((index * itemWidth).toFloat() + ((itemWidth - mPadding) / 2).toFloat() + mPaintWidth / 2, mPaintWidth / 2, ((index + 1) * itemWidth - (itemWidth - mPadding) / 2).toFloat(), mHeight - mPaintWidth / 2, mPaints[index])
    }

    /**
     * 画圆形
     * @param canvas
     * @param index
     */
    private fun drawRound(canvas: Canvas, index: Int) {
        val itemWidth = mWidth / mArrowCount
        val radius = if (itemWidth > mHeight) (mHeight - mPaintWidth) / 2 else (itemWidth - mPaintWidth) / 2
        canvas.drawCircle((index * itemWidth + itemWidth / 2).toFloat(), (mHeight / 2).toFloat(), radius / 2, mPaints[index])
    }

    /**
     * 根据预设的情况绘制不同的图形
     * @param canvas
     * @param index
     */
    private fun drawFigure(canvas: Canvas, index: Int) {
        when (mFigure) {
            Figure.RECTANGLE -> drawRectangle(canvas, index)
            Figure.ROUND -> drawRound(canvas, index)
            Figure.ARROWS -> drawArrows(canvas, index)
        }
    }

    /**
     * 修改画笔颜色，根据透明度
     * @param index
     */
    private fun changePaintColor(index: Int) {
        val alpha = (mBaseAlphas[index].toDouble() / (mAlphaArea[1] - mAlphaArea[0]) * 255).toInt()
        mPaints[index].alpha = 255 - alpha
        mBaseAlphas[index] = addInArea(mBaseAlphas[index])
    }

    /**
     * 范围内增加
     * @param base
     * @return
     */
    private fun addInArea(base: Int): Int {
        var result = base + mSpeed / mPatch
        if (result > mAlphaArea[1]) {
            result = result - mAlphaArea[1] + mAlphaArea[0]
        }
        return result
    }
}
